#ifndef   	BASIC_PARSER_H
#define   	BASIC_PARSER_H

#include "parser.h"

namespace eg {

using namespace std;

//==================================================================================================
//                                      Basic parsers
//==================================================================================================


// A parser which accept end of input
class eof: public parser {

public:
	string parser_name() {
			return "eof";
		}

	bool parse(bool gen_ast = true);

};

// Parser of a given characer 'c'
class a_char_parser: public parser {

public:

	a_char_parser(char c) :
		char_to_match(c) {
	}

	string parser_name() {
				if (char_to_match == '\n')
					return "new line ";
				else return string("'") + char_to_match + '\'';

			}

	bool parse(bool gen_ast = true);

	string to_string() {
		return string("'") + char_to_match + '\'';
	}

private:

	char char_to_match;

};

// Parser of a given string "s"
class a_string_parser: public parser {

public:

	a_string_parser(string s) :
		string_to_match(s) {
	}

	bool parse(bool gen_ast = true);

	string to_string() {
		return string("\"") + string_to_match + '"';
	}
	string parser_name() {
		return "a word " + string_to_match ;
				}


private:

	string string_to_match;

};

// Parser for a character class [...]
class char_class_parser: public parser {

public:

	char_class_parser(string cl) :
		class_to_match(cl) {
	}

	bool parse(bool gen_ast = true);

	string to_string() {
		return string("[") + class_to_match + ']';
	}
	string parser_name() {
			return "one of this characters " + class_to_match ;
					}


private:

	string class_to_match;

};

// Parser for a character range [a-b]
class char_range_parser: public parser {

public:

	char_range_parser(char from, char until) :
		a(from), b(until) {
	}

	bool parse(bool gen_ast = true);

	string to_string() {
		return string("[") + "'" + a + '-' + "'" + b + ']';
	}
	string parser_name(){
			//return string("[") + "'" + a + '-' + "'" + b + ']';
			return "diferent in char";

					}


private:

	const char a, b;

};

// Parser for any character (.)
class some_char_parser: public parser {

public:

	some_char_parser() {
	}

	bool parse(bool gen_ast = true);

	string to_string() {
		return string(".");
	}
	string parser_name() {
		string c;
				return " 'maybe parser' ";
						}

};

// Base class for unary operators parsers (!P,&P,P*,P+,P? and rule)
class unary_parser: public parser {

public:

	unary_parser(parser * arg) :
		argument(arg) {
	}
	~unary_parser() {
		if (!is_a_rule())
			delete argument;
	}
	parser * get_arg() const {
		return argument;
	}

	bool left_recursive(parser * from);

protected:

	parser * argument;

};

//a error parser to skip all until recuperation point

class error_parser: public parser {

public:

	error_parser(char rp, char la) :
		rec_point(rp),look_ahead(la) {
	}

	bool parse(bool gen_ast = true);

	string to_string() {
		return string("'") +  '\'';
	}
	string parser_name() {
			string c = "error";
					return c;
							}


private:

	char rec_point;
	char look_ahead;


};

} // namespace eg

#endif 	

